'''
Author: StormAX 724456475@qq.com
Date: 2024-03-22 15:13:05
LastEditors: StormAX 724456475@qq.com
LastEditTime: 2024-03-23 21:22:28
FilePath: \debug_client\main.py
Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
'''
from typing import Dict
from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtGui import*
from form_ui import Ui_MainWindow
import sys
from msg_loop import Worker
from json_viewer import JSONViewer
import os.path as osp
import os
from pathlib import Path
import json
    
def sort_msg(item):
    return item["timestamp"]
    
class MainWindow(QMainWindow):
    def __init__(self) -> None:
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.register_action()
        self.msg_buf = []
        self.msg_index = dict()
        self.ui.jsonList.setSizeAdjustPolicy(QListWidget.AdjustToContents)
        self.ui.jsonList.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.clicked_index = None
        
        # 创建线程管理器
        self.worker_thread = None
        self.worker = None
        self.export_path = './logs'
            
    def resizeEvent(self, event):
        super().resizeEvent(event)
        self.jsonWidgetSize = self.ui.jsonList.size()
        self.jsonItemSize = QSize(self.jsonWidgetSize.width() + 10, self.jsonWidgetSize.height() - 20)
        for index in range(self.ui.jsonList.count()):
            item = self.ui.jsonList.item(index)
            json_widget = self.ui.jsonList.itemWidget(item)
            json_widget.resize(self.jsonItemSize)
            
    def register_action(self):
        self.ui.procList.clicked.connect(self.on_proclist_clicked)
        self.ui.titleList.clicked.connect(self.on_titleList_clicked)
        self.ui.connect.clicked.connect(self.on_connect_clicked)
        self.ui.export_2.clicked.connect(self.on_export_clicked)
        self.ui.import_2.clicked.connect(self.on_import_clicked)
        self.ui.actionSearch.clicked.connect(self.on_actionSearch_clicked)
        self.ui.selectedSearch.clicked.connect(self.on_selectedSearch_clicked)
        self.ui.globalSearch.clicked.connect(self.on_globalSearch_clicked)
        self.ui.serialize.clicked.connect(self.on_serialize_clicked)
        self.ui.clear.clicked.connect(self.on_clear_clicked)
        
    def on_titleList_clicked(self, index):
        self.clicked_index = index.row()
        self.update_content_view(self.clicked_index)
        
    def update_content_view(self, index):       
        self.popluateProcList(self.msg_buf[index][1])
        self.populateJsonList(self.msg_buf[index][2])

    def popluateProcList(self, data_list: list):
        self.ui.procList.clear()
        for data in data_list:
            item = QListWidgetItem(data)
            self.ui.procList.addItem(item)

    def populateJsonList(self, json_data_list: list):
        self.ui.jsonList.clear()
        # self.ui.jsonList.setCurrentIndex(0)
        self.jsonWidgetSize = self.ui.jsonList.size()
        self.jsonItemSize = QSize(self.jsonWidgetSize.width() - 10, self.jsonWidgetSize.height() - 30)
        # Add JsonWidgets to QListWidget
        for data in json_data_list:
            item = QListWidgetItem()
            item.setSizeHint(self.jsonItemSize)
            
            json_viewer = JSONViewer(data, self.ui.jsonList)
            self.ui.jsonList.addItem(item)
            self.ui.jsonList.setItemWidget(item, json_viewer)
        
    def on_proclist_clicked(self, index):
        self.ui.jsonList.scrollTo(index, QListView.PositionAtTop)
        
    def on_connect_clicked(self):
        ip = self.ui.ip.text()
        self.start_thread(ip)

    def start_thread(self, ip):
        if self.worker is not None:
            self.worker.stop()
            self.worker_thread.quit()
            self.worker_thread.wait()
            self.worker_thread.deleteLater()
            del self.worker

        self.worker = Worker(ip, self.msg_callback)
        self.worker_thread = QThread()
        self.worker.moveToThread(self.worker_thread)
        self.worker_thread.started.connect(self.worker.do_work)
        self.worker_thread.start()

    def msg_callback(self, msg):        
        if msg[0] not in self.msg_index:
            self.msg_buf.append((msg[0], [], []))
            self.msg_index[msg[0]] = self.ui.titleList.count()
            item = QListWidgetItem(str(msg[0]))
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Unchecked)
            self.ui.titleList.addItem(item)
        self.msg_buf[self.msg_index[msg[0]]][1].append(msg[1])
        self.msg_buf[self.msg_index[msg[0]]][2].append(msg[2])

    def on_export_clicked(self):
        checked = []
        for row in range(self.ui.titleList.count()):
            item = self.ui.titleList.item(row)
            if item.checkState() == Qt.Checked:
                checked.append((self.msg_buf[row][0], self.msg_buf[row][2]))
        if not osp.exists(self.export_path):
            os.mkdir(self.export_path)
            
        for title, content in checked:
            with open(osp.join(self.export_path, str(title) + '.json'), 'w') as file:
                json.dump(content, file, indent=4)
            
    def on_import_clicked(self):
        file_dialog = QFileDialog(self)
        file_dialog.setNameFilter("Text files (*.json)")
        file_dialog.setViewMode(QFileDialog.Detail)
        filename, _ = file_dialog.getOpenFileName(self, "Open File", "", "Json files (*.json)")

        # 如果有选择文件
        if filename:
            # 读取文件内容并显示在文本框中
            with open(filename, "r") as file:
                json_data = json.load(file)
                process = []
                for item in json_data:
                    process.append(item["PROCESS"])
            filename = Path(filename).stem
            self.msg_buf.append((filename, process, json_data))
            item = QListWidgetItem(filename)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Unchecked)
            self.ui.titleList.addItem(item)
        
    def on_actionSearch_clicked(self):
        keyword = self.ui.actionKey.text().strip()
        if keyword:
            indexs = []
            for index in range(self.ui.jsonList.count()):
                item = self.ui.jsonList.item(index)
                jsonViewer = self.ui.jsonList.itemWidget(item)
                founded = jsonViewer.highLightKeyword(keyword)
                if founded:
                    indexs.append(index)
        self.clear_proclist_color()
        self.highlight_processlist(indexs)
    
    def highlight_processlist(self, indexs: list):
        if len(indexs) != 0:
            for index in indexs:
                item = self.ui.procList.item(index)
                if item is not None:
                    item.setBackgroundColor(QColor(Qt.yellow))
                    
    def clear_proclist_color(self):
        for i in range(self.ui.procList.count()):
            item = self.ui.procList.item(i)
            if item is not None:
                item.setBackground(QColor("transparent"))
                
    def clear_titlelist_color(self):
        for i in range(self.ui.titleList.count()):
            item = self.ui.titleList.item(i)
            if item is not None:
                item.setBackground(QColor("transparent"))
        
    def on_selectedSearch_clicked(self):
        keyword = self.ui.keyword.text().strip()
        if keyword:
            self.clear_titlelist_color()
            for row in range(self.ui.titleList.count()):
                item = self.ui.titleList.item(row)
                if item.checkState() == Qt.Checked:
                    if keyword in json.dumps(self.msg_buf[row][2]):
                        item.setBackgroundColor(QColor(Qt.yellow))
                        self.ui.actionKey.setText(keyword)
                    else:
                        item.setCheckState(Qt.Unchecked)

    def on_globalSearch_clicked(self):
        keyword = self.ui.keyword.text().strip()
        if keyword:
            self.clear_titlelist_color()
            for row in range(self.ui.titleList.count()):
                item = self.ui.titleList.item(row)
                if keyword in json.dumps(self.msg_buf[row][2]):
                    item.setBackgroundColor(QColor(Qt.yellow))
                    self.ui.actionKey.setText(keyword)
        
    def on_serialize_clicked(self):
        if self.clicked_index is None: return
        
        json_data = self.msg_buf[self.clicked_index][2]
        msgs = []
        for item in json_data:
            msgs.extend(item["MSG"])
        msgs = sorted(msgs, key=sort_msg)
        json_dialog = JSONViewer(msgs, None)
        json_dialog.show()
        
    def on_clear_clicked(self):
        self.msg_buf.clear()
        self.msg_index.clear()
        self.ui.titleList.clear()
        self.ui.procList.clear()
        self.ui.jsonList.clear()
    
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()

    def on_about_to_quit():
        if window.worker_thread is not None:
            window.worker.stop()
            window.worker_thread.quit()
            window.worker_thread.wait()
            window.worker_thread.deleteLater()
    
    # 当应用程序终止时，关闭所有后台线程
    app.aboutToQuit.connect(on_about_to_quit)

    window.show()
    sys.exit(app.exec_())
